package com.sdlight.snowflake.aop;

import cn.hutool.core.util.StrUtil;
import com.sdlight.snowflake.conf.AppConfig;
import com.sdlight.snowflake.dto.ApiRespBase;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 记录接口时间消耗.
 *
 * @author lihaitao
 */
@Component
@Aspect
@Slf4j
public class TimeUsedAspect {

    @Autowired
    private AppConfig appConfig;

    /**
     * 记录执行的时间.
     *
     * @param joinPoint 切入点
     * @return 结果
     * @throws Throwable 异常
     */
    @Around("execution(public * com.sdlight.*.controller..* (..))")
    public Object timeUsed(final ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录开始时间
        long begin = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 记录结束时间
        long end = System.currentTimeMillis();
        long takeTime = end - begin;
        if (result instanceof ApiRespBase) {
            ApiRespBase resp = (ApiRespBase) result;
            resp.setTime(String.valueOf(takeTime));
        }
        if (takeTime > appConfig.getWarnExecGtMs()) {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //记录请求的内容
            String url = request.getRequestURL().toString();
            log.warn(StrUtil.format("execution of {} used {} ms", url, takeTime));
        }
        return result;
    }
}
